﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using HostTool.Core;
using Microsoft.Win32;


namespace HostTool
{
    public partial class Main : Form
    {
        /// <summary>
        /// Host文件操作类
        /// </summary>
        private static readonly HostManage HostManage = new HostManage();

        private bool _searchState = true;

        public Main()
        {
           
            InitializeComponent();   
        }

        private void Main_Load(object sender, EventArgs e)
        {
            HostDataSource.DataSource = HostManage.CurrentHosts;
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            string ip = txtIP.Text.Trim();
            string domain = txtDomain.Text.Trim();
            bool enable = chbEnable.CheckState == CheckState.Checked || chbEnable.CheckState == CheckState.Indeterminate;
            if (string.IsNullOrWhiteSpace(ip) || !ip.IsIP())
            {
                txtIP.Focus();
                MessageBox.Show(@"请输入正确IP");
            }
            else if (string.IsNullOrWhiteSpace(domain) || !domain.IsDomain())
            {
                txtDomain.Focus();
                MessageBox.Show(@"请输入正确Domain");
            }
            else
            {
                Host host = new Host
                {
                    IP = ip,
                    Domain = domain,
                    Enable = enable
                };
                if (HostManage.Verify(host))
                {
                    if (HostManage.Add(host))
                    {
                        HostDataSource.Add(host);
                        HostDataGrid.DataSource = HostDataSource;
                        MessageBox.Show("添加成功");
                    }
                    else
                    {
                        MessageBox.Show("添加失败");
                    }
                }
                else
                {
                    MessageBox.Show(@"输入IP地址与域名已同时存在");
                }
            }
        }

        private void btnDel_Click(object sender, EventArgs e)
        {
            if (HostDataGrid.CurrentRow == null)
            {
                MessageBox.Show("请选择一行数据");
                return;
            }
            var ip = HostDataGrid.Rows[HostDataGrid.CurrentRow.Index].Cells[0].Value.ToString();
            var domain = HostDataGrid.Rows[HostDataGrid.CurrentRow.Index].Cells[1].Value.ToString();
            var host = new Host { Domain = domain, IP = ip };
            HostManage.DeleteHost(host);
            HostDataSource.DataSource = HostManage.CurrentHosts;
            HostDataGrid.DataSource = HostDataSource;
            MessageBox.Show("删除成功");
        }

        private void btnBackup_Click(object sender, EventArgs e)
        {
            safdSave.Filter = "备份文件(*.bak)|*.bak";
            safdSave.RestoreDirectory = true;
            safdSave.ShowDialog();
            if (safdSave.ShowDialog() != DialogResult.OK) return;
            string localFilePath = safdSave.FileName; //获得文件路径 
            HostManage.BackupHost(localFilePath);
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("explorer.exe", HostManage.HostPath);
        }

        private void btnRestore_Click(object sender, EventArgs e)
        {
            opfImport.ShowDialog();
            opfImport.InitialDirectory = "c:\\";//注意这里写路径时要用c:\\而不是c:\
            opfImport.Filter = "文本文件|*.*|C#文件|*.cs|所有文件|*.*";
            opfImport.RestoreDirectory = true;
            opfImport.FilterIndex = 1;
            if (opfImport.ShowDialog() == DialogResult.OK)
            {
                HostManage.RestoreHost(opfImport.FileName);
                HostDataSource.DataSource = HostManage.CurrentHosts;
            }
        }

        private void txtIP_KeyUp(object sender, KeyEventArgs e)
        {
            if (_searchState)
            {
                Search();
            }
        }

        private void txtDomain_KeyUp(object sender, KeyEventArgs e)
        {
            if (_searchState)
            {
                Search();
            }
        }

        private void chbEnable_CheckStateChanged(object sender, EventArgs e)
        {
            if (_searchState)
            {
                Search();
            }
        }

        private void btnPing_Click(object sender, EventArgs e)
        {
            var ip = HostManage.DomainPing(txtDomain.Text);
            if (ip.IsNull()) return;
            txtIP.Text = ip;
            MessageBox.Show(ip);
        }

        private void HostDataGrid_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            var hosts = HostDataSource.DataSource as List<Host>;
            if (hosts == null || !hosts.Any()) return;
            switch (HostDataGrid.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection)
            {
                case SortOrder.None:
                case SortOrder.Ascending:
                    if (e.ColumnIndex == 0)
                        hosts = hosts.OrderByDescending(h => h.IP).ToList();
                    if (e.ColumnIndex == 1)
                        hosts = hosts.OrderByDescending(h => h.Domain).ToList();
                    if (e.ColumnIndex == 2)
                        hosts = hosts.OrderByDescending(h => h.Enable).ToList();
                    HostDataGrid.DataSource = hosts;
                    HostDataGrid.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
                    break;
                case SortOrder.Descending:
                    if (e.ColumnIndex == 0)
                        hosts = hosts.OrderBy(h => h.IP).ToList();
                    if (e.ColumnIndex == 1)
                        hosts = hosts.OrderBy(h => h.Domain).ToList();
                    if (e.ColumnIndex == 2)
                        hosts = hosts.OrderBy(h => h.Enable).ToList();
                    HostDataGrid.DataSource = hosts;
                    HostDataGrid.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
                    break;
            }
        }

        private void HostDataGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex > -1 && e.ColumnIndex == 1)
            {
                var domain = HostDataGrid.Rows[e.RowIndex].Cells[1].Value.ToString();
                System.Diagnostics.Process.Start(DefaultWebBrowserFilePath(), domain);   
            }
            else if (e.RowIndex > -1 && e.ColumnIndex == 0)
            {
                HostDataGrid.Rows[e.RowIndex].Cells[0].ReadOnly = false;
            }             
        }
             
        private void HostDataGrid_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex <= -1 || e.ColumnIndex != 2) return;
            var host = GetCurrentRowHost(e.RowIndex);
            if (host == null)
            {
                MessageBox.Show("请选择一行数据");
                return;
            }
            host.Enable = !host.Enable;
            HostManage.Update(host);

            if (host.Enable)
            {
                var rows = from DataGridViewRow row in HostDataGrid.Rows
                           where row.Index > 0
                           select row;
                foreach (DataGridViewRow row in rows.Where(row => row.Cells[1].Value.ToString() == host.Domain))
                {
                    HostDataGrid.Rows[row.Index].Cells[2].Value = false;
                }
            }
            HostDataGrid.Rows[e.RowIndex].Cells[2].Value = host.Enable;
            HostManage.HostsWriterFile();
            MessageBox.Show("修改成功");
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            txtIP.Text = "";
            txtDomain.Text = "";
            chbEnable.CheckState = CheckState.Indeterminate;
            Search();
        }

        #region

        /// <summary>
        /// 获取默认浏览器的路径
        /// </summary>
        /// <returns></returns>
        private static String DefaultWebBrowserFilePath()
        {
            RegistryKey key = Registry.ClassesRoot.OpenSubKey("http\\shell\\open\\command", false);
            String path = key.GetValue("").ToString();
            if (path.Contains("\""))
            {
                path = path.TrimStart('"');
                path = path.Substring(0, path.IndexOf('"'));
            }
            key.Close();
            return path;
        }

        /// <summary>
        /// 获取当前选中行的Host数据
        /// </summary>
        /// <returns></returns>
        private Host GetCurrentRowHost(int rowIndex)
        {
            if (rowIndex != -1)
            {
                var row = HostDataGrid.Rows[rowIndex];
                return new Host
                {
                    IP = row.Cells[0].Value.ToString().Trim(),
                    Domain = row.Cells[1].Value.ToString().Trim(),
                    Enable = Convert.ToBoolean(row.Cells[2].Value.ToString())
                };
            }
            return null;
        }

        /// <summary>
        /// 通用搜索方法
        /// </summary>
        private void Search()
        {
            _searchState = false;
            var hosts = HostManage.CurrentHosts.AsQueryable();

            if (!string.IsNullOrEmpty(txtIP.Text))
                hosts = hosts.Where(h => h.IP.Contains(txtIP.Text));

            if (!string.IsNullOrEmpty(txtDomain.Text))
                hosts = hosts.Where(h => h.Domain.Contains(txtDomain.Text));

            if (chbEnable.CheckState == CheckState.Checked)
                hosts = hosts.Where(h => h.Enable);

            if (chbEnable.CheckState == CheckState.Unchecked)
                hosts = hosts.Where(h => !h.Enable);

            HostDataSource.DataSource = hosts.ToList();
            _searchState = true;
        }

        #endregion
    }
}
